#ifndef __NODE_H__
#define __NODE_H__

#include "stdafx.h"
#include "vec3.h"
#include <iostream>
#include <list>

#define INVALID_TAG -9001

namespace GeorgeLib
{

	class DLLEXPORT Node
	{
	public:

		Node(void);
		virtual ~Node(void);

		// Override me! Initialise whatever!
		virtual bool Init(void);

		// Override me! Renders only please!
		virtual void Draw(void);

		// Override me! Update only!
		virtual void Update(float delta);

		// Draw all children
		void DrawChildren(void);

		// Update all children
		void UpdateChildren(float delta);

		// Add a child
		virtual void AddChild(Node* child);

		// Get a specific child by its tag
		Node* GetChild(int tag);

		// Get the whole list of children
		list<Node*>* GetChildren(void);

		int GetChildrenCount(void);

		// Remove a child
		void RemoveChild(Node* child);

		// Remove a child by its identifying tag
		void RemoveChildbyTag(int tag);

		// Set the parent node of this node
		void SetParent(Node* parent);

		// Get the parent node of this node
		Node* GetParent(void);

		void SetTag(int tag);
		int  GetTag(void);

		// Transformation Functions
		void Translate(float x, float y, float z);
		void Rotate(float angle, float x, float y, float z);
		void Scale(float x, float y, float z);
		void Translate(vec3 translate);
		void Rotate(float angle, vec3 rotate);
		void Scale(vec3 scale);

		// Get/Set World Position
		vec3 getWorldPos(void);
		void setWorldPos(vec3 v);

		// Get position relative to parent
		vec3 getRelativePos(void);

		// Get Rotation values
		vec3 getRotation(void);

		// Get Scale values
		vec3 getScale(void);

		// Boolean to draw this node
		bool bDraw;

		// World Position of this node
		vec3 wPos;

		// Rotation values of this node
		vec3 *mRot;

		// Scale values of this node
		vec3 *mScale;

		// Integer identifier
		int tag;

private:

		// List of Child Nodes
		list<Node*> *children;

		// Weak reference to parent
		Node * parent;

		typedef list<Node*>::iterator ListIter;
	};

} // namespace GeorgeLib

#endif